﻿/// <summary>
/// https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
/// </summary>
public class Solution
{
    /// <summary>
    /// 
    /// </summary>
    /// <param name="s"></param>
    /// <param name="arrow"></param>
    /// <param name="appearedCharsToAddAndStop"></param>
    /// <returns>是否达到末尾</returns>
    private bool TryMoveRight(string s, ref int arrow, Queue<char> appearedCharsToAddAndStop)
    {
        for (; ; )
        {
            char c = s[arrow + 1];
            if (appearedCharsToAddAndStop.Contains(c))
                return false;
            appearedCharsToAddAndStop.Enqueue(c);
            arrow++;
            if (arrow == s.Length - 1)
                return true;
        }
    }

    public int LengthOfLongestSubstring(string s)
    {
        if (s == string.Empty)
            return 0;
        if (s.Length == 1)
            return 1;

        Queue<char> appearedChars = new Queue<char>();
        int max = 1;
        int left = 0;
        int right = 0;
        appearedChars.Enqueue(s[0]);

        for (; ; )
        {
            var ended = this.TryMoveRight(s, ref right, appearedChars);
            var currentLength = right - left + 1;
            max = max > currentLength ? max : currentLength;
            if (ended)
                return max;
            else
            {
                char aim = s[right + 1];
                left++;
                for (; appearedChars.Dequeue() != aim;)
                    left++;
            }
        }
    }
}